<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */
namespace App\Controller\ws;

use App\Constants\ErrorCode;
use App\Controller\AbstractController;
use App\Service\WebSocketService;
use Hyperf\Contract\OnCloseInterface;
use Hyperf\Contract\OnMessageInterface;
use Hyperf\Contract\OnOpenInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
use Swoole\Http\Request;
use Swoole\WebSocket\Frame;

class WebSocket extends AbstractController implements OnMessageInterface, OnOpenInterface, OnCloseInterface
{
    /**
     * @Inject
     * @var WebSocketService
     */
    protected $websocketService;

    public function onClose($server, int $fd, int $reactorId): void
    {
        $this->websocketService->socketEvent($fd, 'close');
        var_dump('client_id:' . $fd . '已断开');
    }

    public function onMessage($server, Frame $frame): void
    {
        $data = json_decode($frame->data, true);
        if (! empty($data)) {
        }
        $server->push($frame->fd, 'Recv: ' . $frame->data);
    }

    public function onOpen($server, Request $request): void
    {
        var_dump('client_id:' . $request->fd . '已连接');
        $this->websocketService->socketEvent($request->fd, 'open');
    }

    /**
     * 绑定.
     * @param RequestInterface $request
     */
    public function bindUser()
    {
        $fd = $this->request->post('client_id', '');
        $channel = $this->request->post('channel', '');
        if (! empty($fd) && ! empty($channel)) {
            $this->websocketService->socketEvent((int) $fd, 'bind', $this->request->all());
            return $this->success([]);
        }
        return $this->success([], ErrorCode::PARAM_ERROR);
    }

    /**
     * 推送消息.
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function pushNotice()
    {
        $channel = $this->request->post('channel');
        $this->websocketService->pushByChannel($channel);
        return $this->success();
    }
}
